"""
Basic data structure used for general trading function in VN Trader.
"""

from dataclasses import dataclass
from dataclasses_json import dataclass_json
from datetime import date, datetime
from logging import INFO
import time
from vn_local.trader.constant import BinanceContractType, Direction, Exchange, Interval, Offset, Status, Product, \
    OptionType, \
    OrderType, StopOrderStatus, ApiSource

ACTIVE_STATUSES = set(
    [Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED, Status.CANCELLING, StopOrderStatus.TRIGGERED])

CANCELLABLE_STATUSES = set([Status.NOTTRADED, Status.PARTTRADED, Status.FAILED])
CANCELLABLE_EXCHANGE_STATUSES = set([Status.NOTTRADED, Status.PARTTRADED])
FINISH_STATUES = set([Status.ALLTRADED, Status.CANCELLED, Status.REJECTED])
OMS_STATUSES = set([Status.PENDING, Status.CANCELLING, Status.UNKNOWN, Status.FAILED])


def seconds_over_order_create(vt_orderid) -> int:
    # 返回距离创建过了多少秒
    now = time.time_ns()
    order_time = int(vt_orderid.split(".")[1])
    time_passed = int((now - order_time) * 0.000000001)
    return time_passed


def seconds_over_order_cancelling_or_querying(update_time) -> int:
    now = int(time.time() * 1e6)
    time_passed = int((now - update_time) * 0.000001)
    return time_passed


@dataclass
class BaseData:
    """
    Any data object needs a gateway_name as source
    and should inherit base data.
    """

    gateway_name: str


@dataclass
class TickData(BaseData):
    """
    Tick data contains information about:
        * last trade in market
        * orderbook snapshot
        * intraday market statistics.
    """

    symbol: str
    exchange: Exchange
    datetime: datetime
    date: date = ""
    time: str = ""  # '%H:%M:%S.%f'
    trading_day: str = ""  # '%Y-%m-%d'

    ts: int = 0  # 交易所时间戳
    tsNet: int = 0  # 到达网卡时间戳
    tsParse: int = 0  # 编译后推送时间戳
    tsGateway: int = 0  # 到达gateway的时间
    tsUpdate: int = 0  # 更新进腿的时间

    name: int = 0
    volume: float = 0
    open_interest: float = 0
    last_price: float = 0
    last_volume: float = 0
    limit_up: float = 0
    limit_down: float = 0

    open_price: float = 0
    high_price: float = 0
    low_price: float = 0
    pre_close: float = 0

    bid_price_1: float = 0
    bid_price_2: float = 0
    bid_price_3: float = 0
    bid_price_4: float = 0
    bid_price_5: float = 0

    ask_price_1: float = 0
    ask_price_2: float = 0
    ask_price_3: float = 0
    ask_price_4: float = 0
    ask_price_5: float = 0

    bid_volume_1: float = 0
    bid_volume_2: float = 0
    bid_volume_3: float = 0
    bid_volume_4: float = 0
    bid_volume_5: float = 0

    ask_volume_1: float = 0
    ask_volume_2: float = 0
    ask_volume_3: float = 0
    ask_volume_4: float = 0
    ask_volume_5: float = 0

    def __post_init__(self):
        """"""
        if isinstance(self.exchange, Exchange):
            self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        else:
            self.vt_symbol = f"{self.symbol}.{self.exchange}"


@dataclass
class PublicTradeData(BaseData):
    symbol: str
    exchange: Exchange
    datetime: datetime
    name: int = 0

    ts: int = 0
    tsNet: int = 0
    tsParse: int = 0
    tsGateway: int = 0

    direction: Direction = None
    price: float = 0
    volume: float = 0

    def __post_init__(self):
        """"""
        if isinstance(self.exchange, Exchange):
            self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        else:
            self.vt_symbol = f"{self.symbol}.{self.exchange}"


@dataclass
class BarData(BaseData):
    """
    Candlestick bar data of a certain trading period.
    """

    symbol: str
    exchange: Exchange
    datetime: datetime

    interval: Interval = None
    volume: float = 0
    open_interest: float = 0
    open_price: float = 0
    high_price: float = 0
    low_price: float = 0
    close_price: float = 0

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass_json
@dataclass
class OrderData(BaseData):
    """
    Order data contains information for tracking lastest status
    of a specific order.
    """

    symbol: str
    exchange: Exchange
    orderid: str

    type: OrderType = OrderType.LIMIT
    direction: Direction = None
    offset: Offset = Offset.NONE
    price: float = 0
    volume: float = 0
    traded: float = 0
    status: Status = Status.SUBMITTING
    datetime: datetime = None
    insert: int = 0
    update: int = 0
    date: str = ""
    time: str = ""
    cancel_time: str = ""
    reference: str = ""
    error_id: int = 0,
    error_msg: str = ""
    reduce_only: bool = False
    is_maker: bool = False
    api_source: ApiSource = None

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        self.vt_orderid = f"{self.gateway_name}.{self.orderid}"

        # self.untraded = self.volume - self.traded
        #
        # # With millisecond
        # if self.date and "." in self.time:
        #     if "-" in self.date:
        #         self.datetime = datetime.strptime(" ".join([self.date, self.time]),
        #                                           "%Y-%m-%d %H:%M:%S.%f")
        #     else:
        #         self.datetime = datetime.strptime(" ".join([self.date, self.time]),
        #                                           "%Y%m%d %H:%M:%S.%f")
        # # Without millisecond
        # elif self.date:
        #     if "-" in self.date:
        #         self.datetime = datetime.strptime(" ".join([self.date, self.time]),
        #                                           "%Y-%m-%d %H:%M:%S")
        #     else:
        #         self.datetime = datetime.strptime(" ".join([self.date, self.time]),
        #                                           "%Y%m%d %H:%M:%S")

    def is_active(self) -> bool:
        """
        Check if the order is active.
        """
        if self.status in ACTIVE_STATUSES:
            return True
        else:
            return False

    def create_cancel_request(self) -> "CancelRequest":
        """
        Create cancel request object from order.
        """
        req = CancelRequest(
            orderid=self.orderid, symbol=self.symbol, exchange=self.exchange
        )
        return req

    def create_replace_request(self) -> "ReplacelRequest":
        """
        Create cancel request object from order.
        """
        req = ReplaceRequest(
            orderid=self.orderid, symbol=self.symbol, exchange=self.exchange, direction=self.direction
        )
        return req


@dataclass_json
@dataclass
class TradeData(BaseData):
    """
    Trade data contains information of a fill of an order. One order
    can have several trade fills.
    """

    symbol: str
    exchange: Exchange
    orderid: str
    tradeid: str
    direction: Direction = None

    offset: Offset = Offset.NONE
    price: float = 0
    volume: float = 0

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        self.vt_orderid = f"{self.gateway_name}.{self.orderid}"
        self.vt_tradeid = f"{self.gateway_name}.{self.tradeid}"


@dataclass_json
@dataclass
class OrderTradeData(BaseData):
    symbol: str
    exchange: Exchange
    orderid: str

    order: OrderData = None
    trade: TradeData = None

    type: OrderType = OrderType.LIMIT
    direction: Direction = None
    offset: Offset = Offset.NONE
    price: float = 0
    volume: float = 0
    traded: float = 0
    trade_diff: float = 0.0
    trade_price: float = 0.0
    status: Status = Status.SUBMITTING
    exchange_status: Status = Status.SUBMITTING

    insert: int = 0
    update: int = 0
    tsSent: int = 0
    tsNet: int = 0

    api_source: ApiSource = None
    is_maker: bool = False
    reduce_only: bool = False
    error_id: int = 0
    error_msg: str = ""
    reference: str = ""
    query_num: int = 0
    cancel_num: int = 0

    latest_cancel_time: int = 0  # 16位
    latest_query_time: int = 0  # 16位

    def __post_init__(self):
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        self.vt_orderid = f"{self.gateway_name}.{self.orderid}"
        self.tradeid = str(self.update)
        self.vt_tradeid = f"{self.gateway_name}.{self.tradeid}"

    def is_active(self) -> bool:
        """
        Check if the order is active.
        """
        if self.status in ACTIVE_STATUSES:
            return True
        else:
            return False

    def is_pending(self) -> bool:
        if self.status == Status.PENDING:
            return True
        else:
            return False

    def is_cancelling(self) -> bool:
        if self.status == Status.CANCELLING:
            return True
        else:
            return False

    def is_exchange_status(self) -> bool:
        if self.status in OMS_STATUSES:
            return False
        else:
            return True

    def is_cancellable(self) -> bool:
        """
        Check if the order is active.
        """
        # 排除正在取消中的订单
        if self.status not in CANCELLABLE_STATUSES:
            return False

        if self.exchange_status not in CANCELLABLE_EXCHANGE_STATUSES:
            return False

        if self.cancel_num > 0:
            if seconds_over_order_cancelling_or_querying(self.latest_cancel_time) < 1:
                return False

        return True

    def is_submittable(self) -> bool:
        pass

    def is_cancellable_on_cancelling(self, response_tolerant=30) -> bool:
        if not self.exchange_status in CANCELLABLE_STATUSES:
            return False

        if not self.is_cancelling_too_long(response_tolerant=response_tolerant):
            return False

        return True

    def is_cancelling_too_long(self, response_tolerant=30) -> bool:
        if not self.is_cancelling():
            return False

        if not seconds_over_order_cancelling_or_querying(self.latest_cancel_time) > response_tolerant:
            return False

        return True

    def is_querying_too_long(self, response_tolerant=30) -> bool:
        if not seconds_over_order_cancelling_or_querying(self.latest_query_time) > response_tolerant:
            return False

        return True

    def is_pending_too_long(self, response_tolerant=30) -> bool:
        if not self.is_pending():
            return False

        if not seconds_over_order_create(self.vt_orderid) > response_tolerant:
            return False

        return True

    def is_in_flight(self):
        if self.status in (Status.PENDING, Status.CANCELLING):
            return True
        else:
            return False

    def is_finished(self) -> bool:
        if self.status in FINISH_STATUES:
            return True
        else:
            return False

    def create_cancel_request(self) -> "CancelRequest":
        """
        Create cancel request object from order.
        """
        req = CancelRequest(
            orderid=self.orderid, symbol=self.symbol, exchange=self.exchange
        )
        return req

    def create_replace_request(self) -> "ReplacelRequest":
        """
        Create cancel request object from order.
        """
        req = ReplacelRequest(
            orderid=self.orderid, symbol=self.symbol, exchange=self.exchange, direction=self.direction
        )
        return req

    def create_amend_request(self, price, volume) -> "AmendRequest":
        """
        Create amend request object from order.
        """
        req = AmendRequest(orderid=self.orderid, symbol=self.symbol, exchange=self.exchange, price=price, volume=volume)
        return req


@dataclass_json
@dataclass
class PositionData(BaseData):
    """
    Positon data is used for tracking each individual position holding.
    """

    symbol: str
    exchange: Exchange
    direction: Direction

    volume: float = 0
    frozen: float = 0
    price: float = 0
    pnl: float = 0
    liq_price: float = 0
    mark_price: float = 0
    api_source: ApiSource = None
    adl: float = 0
    yd_volume: float = 0
    update_time: int = 0

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        self.vt_positionid = f"{self.vt_symbol}.{self.direction.value}"


@dataclass
class AccountData(BaseData):
    """
    Account data contains information about balance, frozen and
    available.
    """

    exchange: Exchange = Exchange.BINANCE  # 适配高频系统
    currency: str = ""  # 适配高频系统

    available: float = 0
    frozen: float = 0
    pnl: float = 0
    total: float = 0
    api_source: ApiSource = None
    update_time: int = 0

    def __post_init__(self):
        """"""
        self.balance = self.available + self.frozen
        # self.vt_accountid = f"{self.gateway_name}.{self.accountid}"


@dataclass
class LogData(BaseData):
    """
    Log data is used for recording log messages on GUI or in log files.
    """

    msg: str
    level: int = INFO
    prefix: str = "vt"

    def __post_init__(self):
        """"""
        self.time = datetime.now()


@dataclass
class ContractData(BaseData):
    """
    Contract data contains basic information about each contract traded.
    """

    symbol: str
    exchange: Exchange
    name: int
    product: Product
    size: float
    pricetick: float
    margin_rate: float = 0.1  # 保证金比率

    base: str = ""  # 适配高频
    quote: str = ""  # 适配高频

    min_volume: float = 1  # minimum trading volume of the contract
    min_notional: float = 5  # minimum trading notional
    max_market_size: float = 0  # maximum market order size
    stop_supported: bool = False  # whether server supports stop order
    net_position: bool = False  # whether gateway uses net position volume
    history_data: bool = False  # whether gateway provides bar history data
    market_supported: bool = False  # whether gateway supports market order

    option_strike: float = 0
    option_underlying: str = ""  # vt_symbol of underlying contract
    option_type: OptionType = None
    option_expiry: datetime = None
    option_portfolio: str = ""
    option_index: str = ""  # for identifying options with same strike price

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class QuoteData(BaseData):
    """
    Quote data contains information for tracking lastest status
    of a specific quote.
    """

    symbol: str
    exchange: Exchange
    quoteid: str

    bid_price: float = 0.0
    bid_volume: int = 0
    ask_price: float = 0.0
    ask_volume: int = 0
    bid_offset: Offset = Offset.NONE
    ask_offset: Offset = Offset.NONE
    status: Status = Status.SUBMITTING
    datetime: datetime = None
    reference: str = ""

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
        self.vt_quoteid = f"{self.gateway_name}.{self.quoteid}"

    def create_cancel_request(self) -> "CancelRequest":
        """
        Create cancel request object from quote.
        """
        req = CancelRequest(
            orderid=self.quoteid, symbol=self.symbol, exchange=self.exchange
        )
        return req


@dataclass
class BinanceContractData(ContractData):
    # 合约类型
    contract_type: BinanceContractType = None

    # 保证金币种
    margin_asset: str = ""


@dataclass
class SubscribeRequest:
    """
    Request sending to specific gateway for subscribing tick data update.
    """

    symbol: str
    exchange: Exchange
    is_bar: bool = False

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class FundingRequest:
    """
    Request sending to specific gateway for subscribing tick data update.
    """
    symbol: str
    exchange: Exchange

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class ReplaceRequest:
    """
    Request sending to specific gateway for replaceing an existing order.
    """

    orderid: str
    symbol: str
    exchange: Exchange
    direction: Direction

    qry: str = None
    price: str = None

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class AmendRequest:
    orderid: str
    symbol: str
    exchange: Exchange
    volume: float
    price: float

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class OrderRequest:
    """
    Request sending to specific gateway for creating a new order.
    """
    symbol: str
    exchange: Exchange
    direction: Direction
    type: OrderType
    volume: float
    price: float = 0
    offset: Offset = Offset.NONE
    reference: str = ""
    reduce_only: bool = False

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"

    def create_order_data(self, orderid: str, gateway_name: str) -> OrderData:
        """
        Create order data from request.
        """
        order = OrderData(
            symbol=self.symbol,
            exchange=self.exchange,
            orderid=orderid,
            type=self.type,
            direction=self.direction,
            offset=self.offset,
            price=self.price,
            volume=self.volume,
            reference=self.reference,
            reduce_only=self.reduce_only,
            gateway_name=gateway_name,
        )
        return order

    def create_order_trade(self, orderid: str, gateway_name: str) -> OrderTradeData:
        order_trade = OrderTradeData(
            symbol=self.symbol,
            exchange=self.exchange,
            orderid=orderid,
            type=self.type,
            direction=self.direction,
            offset=self.offset,
            price=self.price,
            volume=self.volume,
            gateway_name=gateway_name
        )
        return order_trade


@dataclass
class CancelRequest:
    """
    Request sending to specific gateway for canceling an existing order.
    """

    orderid: str
    symbol: str
    exchange: Exchange

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class CancelAllRequest:
    symbol: str
    exchange: Exchange
    product: Product


@dataclass
class QueryOpenOrderRequest:
    symbol: str
    exchange: Exchange
    product: Product


@dataclass
class HistoryRequest:
    """
    Request sending to specific gateway for querying history data.
    """

    symbol: str
    exchange: Exchange
    start: datetime
    end: datetime = None
    interval: Interval = None

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass
class QuoteRequest:
    """
    Request sending to specific gateway for creating a new quote.
    """

    symbol: str
    exchange: Exchange
    bid_price: float
    bid_volume: int
    ask_price: float
    ask_volume: int
    bid_offset: Offset = Offset.NONE
    ask_offset: Offset = Offset.NONE
    reference: str = ""

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"

    def create_quote_data(self, quoteid: str, gateway_name: str) -> QuoteData:
        """
        Create quote data from request.
        """
        quote = QuoteData(
            symbol=self.symbol,
            exchange=self.exchange,
            quoteid=self.quoteid,
            bid_price=self.bid_price,
            bid_volume=self.bid_volume,
            ask_price=self.ask_price,
            ask_volume=self.ask_volume,
            bid_offset=self.bid_offset,
            ask_offset=self.ask_offset,
            reference=self.reference,
            gateway_name=gateway_name,
        )
        return quote


@dataclass
class PremiumIndexData(BaseData):
    """
    PremiumIndex Data
    """
    symbol: str
    exchange: Exchange
    nextFundingTime: datetime
    lastFundingRate: float
    nextFundingRate: float
    lastFundingRateStr: str
    nextFundingRateStr: str
    nextFundingTimeStr: str
    type: str
    first_earn: str
    second_earn: str
    swap_fee: str = None
    week_fee: str = None
    swap_symbol: str = None
    week_symbol: str = None
    history: str = None

    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}.{self.exchange.value}"


@dataclass_json
@dataclass
class PairLog:
    ts_algo: str
    spread: str
    direction: str
    spread_target_price: float
    spread_cancel_price: float
    active_quote_range: float
    active_quote_space: float
    active_max_volume: float
    active_max_order_nums: int
    ts_spread_data: int
    active_ask_price: float
    active_ask_volume: float
    active_bid_price: float
    active_bid_volume: float
    active_ts: int
    active_tsNet: int
    active_tsGW: int
    active_tsUpdate: int
    passive_ask_price: float
    passive_ask_volume: float
    passive_bid_price: float
    passive_bid_volume: float
    passive_ts: int
    passive_tsNet: int
    passive_tsGW: int
    passive_tsUpdate: int
    active_orderid: int = 0
    active_order_status: str = ""
    active_order_price: float = 0
    active_order_volume: float = 0
    active_filled_volume: float = 0
    active_filled_time: int = 0
    # passive_price_on_active_filled: float = 0
    passive_orderid: int = 0
    passive_order_status: str = ""
    passive_order_price: float = 0
    passive_order_volume: float = 0
    passive_filled_price: float = 0
    passive_filled_volume: float = 0
    passive_filled_time: int = 0

    def if_updated_active(self, vt_orderid):
        if self.active_orderid != vt_orderid:
            return False
        return True

    def if_update_passive(self, vt_orderid):
        if self.passive_orderid != vt_orderid:
            return False
        return True

    def if_order_id_in_pair_log(self, vt_orderid):
        if (self.active_orderid == vt_orderid) or (self.passive_orderid == vt_orderid):
            return True
        return False

    def if_remove(self):
        if self.active_order_status in (Status.CANCELLED.value, Status.REJECTED.value):
            return True

        if self.passive_order_status in (Status.REJECTED.value, Status.ALLTRADED.value):
            return True

        if self.active_order_status in (Status.ALLTRADED.value, Status.CANCELLED.value):
            if not self.passive_order_status:
                return True

        return False

    def if_write(self):
        if self.active_order_status != Status.ALLTRADED.value:
            return False
        if self.passive_order_status != Status.ALLTRADED.value:
            return False

        return True


@dataclass_json
@dataclass
class PfitLog:
    trigger_by: str
    last_p_fit: float
    new_p_fit: float
    p_weight: float
    jump_value: float
    jump_count: int
    p_cex: float
    p_dex: float
    # maximum_buy_price: float
    # minimum_sell_price: float
    ask1_price: float
    bid1_price: float
    paper_top_buy: float = 0
    paper_top_sell: float = 0
    kurtosis: int = 0
    sigma: float = 0
    miu: float = 0
    df: int = 0
    v_dex: int = 0
    v_cex: int = 0
    maker_open_order_nums: int = 0


@dataclass_json
@dataclass
class MonitorInfo:
    latest_p_fit: float = 0
    coin_left: float = 0
    coin_total: float = 0
    usdt_left: float = 0
    usdt_total: float = 0

    sell_frozen: float = 0
    buy_frozen: float = 0

    sell_pending_orders_nums: int = 0
    buy_pending_orders_nums: int = 0
    maker_long_trades: float = 0
    maker_short_trades: float = 0

    maker_long_notional: float = 0
    maker_short_notional: float = 0

    taker_long_trades: float = 0
    taker_short_trades: float = 0

    taker_long_notional: float = 0
    taker_short_notional: float = 0

    taker_pending_orders_nums: int = 0


from dataclasses import dataclass, field
from dataclasses_json import dataclass_json


@dataclass_json
@dataclass
class OrderFlowManager:
    insert_buy_list: list = field(default_factory=list)
    insert_sell_list: list = field(default_factory=list)
    cancel_buy_list: list = field(default_factory=list)
    cancel_sell_list: list = field(default_factory=list)
    key_orders_list: list = field(default_factory=list)

    def update_lists(self, order_trade):
        """
        根据订单状态更新相应的列表并处理订单
        :param order_trade: OrderTradeData，订单回报数据
        """
        vt_orderid = order_trade.vt_orderid
        direction = order_trade.direction

        # 处理关键订单
        if vt_orderid in self.key_orders_list:
            self.key_orders_list.remove(vt_orderid)
            print(f"Key order [{vt_orderid}] 已处理，更新关键订单列表。")
            # 插入下一波订单
            self.insert_next_orders()

        # 根据订单方向处理取消/插入
        if order_trade.status in (Status.CANCELLED, Status.ALLTRADED):
            if direction == Direction.LONG:
                self.cancel_buy_list = self.remove_cancelled_order(self.cancel_buy_list, vt_orderid, "buy")
            elif direction == Direction.SHORT:
                self.cancel_sell_list = self.remove_cancelled_order(self.cancel_sell_list, vt_orderid, "sell")
            self.insert_next_order(direction)

        elif order_trade.status == Status.NOTTRADED:
            if direction == Direction.LONG:
                self.insert_buy_list = self.remove_not_traded_order(self.insert_buy_list, vt_orderid, "buy")
            elif direction == Direction.SHORT:
                self.insert_sell_list = self.remove_not_traded_order(self.insert_sell_list, vt_orderid, "sell")
            self.cancel_next_order(direction)

    def insert_next_order(self, direction):
        """
        根据订单方向插入下一个订单
        """
        if direction == Direction.LONG:
            if self.insert_buy_list:
                order = self.insert_buy_list.pop(0)
                print(f"插入买单：{order}")
        elif direction == Direction.SHORT:
            if self.insert_sell_list:
                order = self.insert_sell_list.pop(0)
                print(f"插入卖单：{order}")

    def cancel_next_order(self, direction):
        """
        根据订单方向取消下一个订单
        """
        if direction == Direction.LONG:
            if self.cancel_buy_list:
                order = self.cancel_buy_list.pop(0)
                print(f"取消买单：{order}")
        elif direction == Direction.SHORT:
            if self.cancel_sell_list:
                order = self.cancel_sell_list.pop(0)
                print(f"取消卖单：{order}")

    def insert_next_orders(self):
        """
        插入下一个买单和卖单
        """
        self.insert_next_order(Direction.LONG)
        self.insert_next_order(Direction.SHORT)

    def remove_cancelled_order(self, cancel_list, vt_orderid, side):
        """
        通用的移除 cancel_list 中指定状态为 cancelled 的订单
        """
        for i, (oid, price) in enumerate(cancel_list):
            if oid == vt_orderid:
                cancel_list.pop(i)
                print(f"移除已取消的 {side} 单：{vt_orderid}")
                return cancel_list
        return cancel_list

    def remove_not_traded_order(self, insert_list, vt_orderid, side):
        """
        通用的移除 insert_list 中状态为 NotTraded 的订单
        """
        for i, order in enumerate(insert_list):
            if order['order_id'] == vt_orderid:
                insert_list.pop(i)
                print(f"移除未成交的 {side} 单：{vt_orderid}")
                return insert_list
        return insert_list
